package com.ntty.utils;

import static io.netty.buffer.Unpooled.copiedBuffer;
import static io.netty.handler.codec.http.HttpHeaderNames.*;
import static io.netty.handler.codec.http.HttpResponseStatus.*;
import static io.netty.handler.codec.http.HttpVersion.*;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import javax.activation.MimetypesFileTypeMap;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.DefaultHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpUtil;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.cookie.Cookie;
import io.netty.handler.codec.http.cookie.ServerCookieDecoder;
import io.netty.handler.codec.http.cookie.ServerCookieEncoder;
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.handler.codec.http.multipart.MemoryAttribute;
import io.netty.util.CharsetUtil;

public class HttpTools {

	// 重定向操作
	public static void sendRedirect(ChannelHandlerContext ctx, String newUri) {
		// 建立响应对象
		FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, FOUND);
		// 设置新的请求地址放入响应对象中去
		response.headers().set(HttpHeaderNames.LOCATION, newUri);
		/*
		 * 使用ctx对象写出并且刷新到SocketChannel中去 并主动关闭连接(这里是指关闭处理发送数据的线程连接)
		 */
		ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
	}

	// 错误信息
	public static void sendErrorPage(ChannelHandlerContext ctx) {
		// 建立响应对象
		sendRedirect(ctx, "/404.jsp");
		/*
		 * 使用ctx对象写出并且刷新到SocketChannel中去 并主动关闭连接(这里是指关闭处理发送数据的线程连接)
		 */

	}

	public static void setContentTypeHeader(HttpResponse response, File file) {
		MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap();
		response.headers().set(HttpHeaderNames.CONTENT_TYPE, mimetypesFileTypeMap.getContentType(file.getPath()));
	}

	public static Map<String, Object> getFormParams(FullHttpRequest fullHttpRequest) {
		Map<String, Object> params = new HashMap<String, Object>();
		// HttpPostMultipartRequestDecoder
		HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), fullHttpRequest);
		List<InterfaceHttpData> postData = decoder.getBodyHttpDatas();
		for (InterfaceHttpData data : postData) {
			if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) {
				MemoryAttribute attribute = (MemoryAttribute) data;
				params.put(attribute.getName(), attribute.getValue());
			}
		}
		return params;
	}

	public static Map<String, Object> getJSONParams(FullHttpRequest fullHttpRequest)
			throws UnsupportedEncodingException {
		Map<String, Object> params = new HashMap<String, Object>();
		ByteBuf content = fullHttpRequest.content();
		byte[] reqContent = new byte[content.readableBytes()];
		content.readBytes(reqContent);
		String strContent = new String(reqContent, "UTF-8");
		JSONObject jsonObject = JSON.parseObject(strContent);
		for (String key : jsonObject.keySet()) {
			params.put(key, jsonObject.get(key));
		}
		return params;
	}

	// 返回text
	public static FullHttpResponse getTextResponse(HttpResponseStatus status, String responseContent) {
		ByteBuf content = copiedBuffer(responseContent, CharsetUtil.UTF_8);
		FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, content);
		response.headers().set("Content-Type", "text/plain;charset=UTF-8;");
		response.headers().set("Content-Length", response.content().readableBytes());
		return response;
	}

	// 返回json
	public static FullHttpResponse getJsonResponse(HttpResponseStatus status, String jsonResult) {
		// 建立响应对象
		FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status,
				Unpooled.copiedBuffer(jsonResult, CharsetUtil.UTF_8));
		// 设置响应头信息
		response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json; charset=UTF-8");
		return response;
		/*
		 * 使用ctx对象写出并且刷新到SocketChannel中去 并主动关闭连接(这里是指关闭处理发送数据的线程连接)
		 */
		// ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
	}

	public static Map<String, Object> getGetParamasFromChannel(FullHttpRequest fullHttpRequest) {
	
		if (fullHttpRequest.method() == HttpMethod.GET) {
			Map<String, Object> params = new HashMap<String, Object>();
			QueryStringDecoder decoder = new QueryStringDecoder(fullHttpRequest.uri());
			Map<String, List<String>> paramList = decoder.parameters();
			for (Map.Entry<String, List<String>> entry : paramList.entrySet()) {
				params.put(entry.getKey(), entry.getValue().get(0));
			}
			return params;
		} else {
			return null;
		}
	}

	public static Map<String, Object> getPostParamsFromChannel(FullHttpRequest fullHttpRequest) {

		if (fullHttpRequest.method() == HttpMethod.POST) {
			Map<String, Object> params = new HashMap<String, Object>();
			String strContentType = fullHttpRequest.headers().get("Content-type").trim();
//	            if (strContentType.contains("x-www-form-urlencoded")) {
			if (strContentType.contains("form")) {
				params = getFormParams(fullHttpRequest);
			} else if (strContentType.contains("application/json")) {
				try {
					params = getJSONParams(fullHttpRequest);
				} catch (UnsupportedEncodingException e) {
					return null;
				}
			} else {
				return null;
			}
			return params;
		}
		return null;
	}
	public static void writeAndClose(ChannelHandlerContext ctx, FullHttpResponse response) {		
		ctx.write(response).addListener(ChannelFutureListener.CLOSE);		
	}
	public static void write(ChannelHandlerContext ctx, FullHttpResponse response, FullHttpRequest request) {
		boolean keepAlive = HttpUtil.isKeepAlive(request);
		if (!keepAlive) {
			ctx.write(response).addListener(ChannelFutureListener.CLOSE);
		} else {
			response.headers().set(CONNECTION, "keep-alive");
			ctx.write(response);
		}
	}
}
